#ifndef DEVICE_H
#define DEVICE_H

#include "Arduino.h"
#include "ErrorCodes.h"

#define DEBUG

#define DBG(x) Serial.print(x);
#define DBGLN(x) Serial.println(x);
//#define DBG(x)
//#define DBGLN(x)

enum DeviceType {
    DIGITAL_SENSOR,
    ANALOG_SENSOR,
    I2C_DEVICE,
    SERIAL_DEVICE,
    INTERRUPT_DEVICE,
    DIGITAL_OUT_DEVICE,
    PWM_DEVICE,
    OTHER_DEVICE
};


//!  \brief  Read a generic Analog or Digital Device.  Base Class for Devices
/*!
Class for reading a generic Analog or Digital Device such as a Motion Detector\n
Baseclass for other devices.  Verifies and stores pin\n
Hardware - Generic Analog or Digital Device\n
\n
e.g. Sound Sensor (ANALOG_SENSOR) - http://www.robotshop.com/dfrobot-sound-sensor-4.html\n
        device.read() - returns 0 to 1024 based on ambient volume\n\
\n
e.g. Motion Sensor (DIGITAL_SENSOR) - http://www.dfrobot.com/index.php?route=product/product&filter_name=motion%20detector&product_id=119\n
        device.read() - returns 0 if no movement, 1 if movement\n
\version 1.3\n
  */
class Device
{
    public:
    Device();
    virtual int16_t read();
    virtual int16_t begin(int pin, DeviceType deviceType);
    void setMetric(bool flag);

    float centigradeToFarenheit(int centi);
    float centimeterToInch(int centi) ;
    int pinToInterrupt(int pin);

    ErrorCode errorCode;
       uint8_t _pin;
    bool metric;
    int _devAddress;  // I2C address
    DeviceType deviceType;

private:
    //static bool wireInitialized;

};

/*!
\mainpage
<b> Arduino Device Library</b>

This is a set of Device libraries that all use the same standard interfaces, such as begin() and read().  This makes
 it  easy to incorporate new devices into your sketches since they all work the same way.  Wherever possible
 they return informative error codes.

<b> Device Library Interfaces</b>

\li <b>Constructors</b> take no parameters.

\li <b>begin(int pin, DeviceType deviceType)</b>  This performs all initialization and returns an errorCode
 or SUCCESS if successful.  PIN is the first parameter for
digital, analog, serial and interrupt sensor libraries.    Note that the begin function uses a PIN even for serial devices (TX Pin), not the
COMM name, likewise it uses the PIN for Interrupt functions, not the Interrupt number.  This allows you to easilly
switch between HW ints and PC ints, and likewise between HW Serial and Software serial. The Device type is the second
 parameter and can be DIGITAL_SENSOR, ANALOG_ SENSOR, I2C_DEVICE, SERIAL_DEVICE, INTERRUPT_DEVICE, DIGITAL_OUT_DEVICE,
 PWM_DEVICE or OTHER_DEVICE. Additional initialization parameters are passed after Sensor Type for some devices.

\li <b>read()</b>  If the device has only one function, then read() performs all work necessary to return the
devices currrent value.  For example, read is used for the distance sensor and simply returns the distance.
No other calls are needed to do a read.

\li <b>readAbc()</b>  If the sensor has multiple functions, then readAbc() returns the devices currrent value for
one of its multiple functions, for example GPS.readLatitude() and GPS.readLongitude()

<b> Currently Supported Devices</b>

\li Compass LSM303 - LSM303 based compasses

\li GPS - Any standard GPS

\li IRController - IR Remote reader (using interrupts rather than using a polling loop).  NEC protocol

\li LiquidCrystal LCD03 - Common small LCD 4x20 etc.

\li Ping - Generic Ultrasonic Distance sensor

\li Temperature DHTxx - Temperature Sensor with DHT11-DHT22 chipset

\li MP3 Player - DFR MP3 player

\li Proximity - Proximity sensor

\li Generic Analog sensor - For example sound volume, etc.

\li Generic Digital Sensor - For example Motion Detector

<b> General rules for the libraries</b>

\li Loops or delays are avoided as much as possible - exceptions include the LCD library which needs to delay to
allow the LCD to process data, and the Temperature sensor which has microsend delays for the communication protocol.
\li The library supports UNO/compatible and Mega2560/compatible systems.
\li It can use any supported hardware pins (UNO/compatible and Mega2560/compatible).
\li Consistent error codes are used (from ErrorCodes.h).  See the Error Codes section for details.

<b> Library Names</b>

All the interface names are generic and hide the specifics of the underlying hardware, however the actual library
name will have a suffix if it is for a specific hardware type.  For example, the temperature sensor library
 is named TemperatureSensor_DHxx.h since it supports the DHT11-DHT22 chip, but the classes and interfaces are generic:
 Temperature(),temperature.begin(), temperature.readTemperature(), temperature.readHumidity(), etc.  This makes it
easy to switch specific hardware types without needing to change any code other than the name of the Device include file.

<b> Pin Assignments</b>

The only time a pin or any hardware specific item is specified is when you call the begin() interface.

All example code uses pin assignments from MyHardware.h. This file contains all the pin assignments and hardware
specific items you use and allows easier
management of pin assignments.  This allows you to easilly move a project to a different hardware setup without any
code changes, just changes to MyHardware.h.  By placing all the pin assignments in one file, it is easy to see if
there are any conflicts and also easy to wire up your Arduino.  It currently contains a section for UNO and a section
for MEGA, but you can set it any way that is convenient.

<b> Metric / Imperial</b>

All libraries use Metric by default.  You can call setMetric(false) to have a device use Imperial units instead

<b>Installation </b>
Download from http://www.zbotic.com/index.php/download/.  This contains all the device libraries.  Unzip whichever
libraries you want plus the Device library into your Arduino folder.  For the IRController library, also unzip the PCInterrupt library.
Each library has example code and SensorTest.ino can also be used to test multiple devices.  To use the examples,
modify myHardware.h in the Device directory to configure your pin setup.
For additional debug information, modify the DBG and DBGLN #defines in Device.h
*/

#endif // DEVICE_H
